﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Automapping;
using Landscape.Business.Entities;
using Landscape.Business.Common;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Validator;
using NHibernate.Validator.Event;
using NHibernate.Validator.Engine;
using NHibernate.Validator.Cfg;
using NHibernate.Validator.Cfg.Loquacious;
using System.Reflection;

namespace Landscape.Business.FNH
{
    public sealed class NHSessionManager
    {
        private static readonly NHSessionManager _SessionManager = new NHSessionManager();
        NHibernate.ISessionFactory _sesisonFactory;
        //NHibernate.Cfg.Configuration _NHConfig = new NHibernate.Cfg.Configuration().Configure();

        private NHSessionManager()
        {
            string conString = Utils.GetConnectionString();
            var cfg = new LandscapeAutoMapingConfig();

            

            var configuration = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2008.ConnectionString(conString).ShowSql())
                //.Diagnostics(d => { d.OutputToFile(@"C:\TPOT Projects\TPOTO Portal\TPOTOperations\TPOTO.WebApp\Logs\Trace.log"); d.Enable(); })
                .ExposeConfiguration(
                c =>
                {
                    c.SetProperty("current_session_context_class", "web");
                    c.SetProperty("cache.provider_class", "NHibernate.Cache.HashtableCacheProvider");
                    c.SetProperty("cache.use_second_level_cache", "true");
                    c.SetProperty("cache.use_query_cache", "true");
                    c.SetProperty("not-found", "ignore");
                    //c.SetProperty("show_sql", "true");                    
                    //c.SetInterceptor(new QueryInterceptor());     
                    ConfigureLandscapeValidator(c);
                })
                .Mappings(m =>
                {
                    m.AutoMappings.Add(
                       AutoMap.AssemblyOf<UserMaster>(cfg)
                       .Conventions.AddFromAssemblyOf<TableNameConvention>()
                       .Conventions.AddFromAssemblyOf<CascadeAll>()
                       .Conventions.AddFromAssemblyOf<PropertyConvention>()                       
                       .Override<SystemResourceMap>(x=>x.References<UserMaster>(exp=>exp.User, "User_id"))                       
                       .Override<SystemModule>(x=>x.HasManyToMany<Department>(exp=>exp.Departments)));
                })
                .BuildConfiguration();
            _sesisonFactory = configuration.BuildSessionFactory();
        }

        public static void ConfigureLandscapeValidator(Configuration pConfiguration)
        {
            var provider = new NHibernateSharedEngineProvider();
            NHibernate.Validator.Cfg.Environment.SharedEngineProvider = provider;

            var nhvConfiguration = new NHibernate.Validator.Cfg.Loquacious.FluentConfiguration();
            nhvConfiguration               
               .SetDefaultValidatorMode(ValidatorMode.UseAttribute)
               .Register(Assembly.Load(typeof(UserMaster).Assembly.FullName)
               .ValidationDefinitions())               
               .IntegrateWithNHibernate
                   .ApplyingDDLConstraints()
                   .RegisteringListeners();

            ValidatorEngine validatorEngine = new ValidatorEngine();//NHibernate.Validator.Cfg.Environment.SharedEngineProvider.GetEngine();
            validatorEngine.Configure(nhvConfiguration);

            ValidatorInitializer.Initialize(pConfiguration, validatorEngine);
        }

        public static NHSessionManager GetManager()
        {
            return _SessionManager;
        }

        public ISession GetSession()
        {
            return this._sesisonFactory.OpenSession();
        }
    }
}
